﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Collections;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace EDIConsole
{
	public class PrjProperty
	{
		/// <summary>
		/// Версия сборки
		/// </summary>
		public static string Version = "ver 1.2012.07.24.0";

		/// <summary>
		/// Log-лист
		/// </summary>
		public static Logger Logs;

		/// <summary>
		///  Имя клиента
		/// </summary>
		public static string ClientName;

		/// <summary>
		/// Путь к серверу
		/// </summary>
		public static string ServerPath;

		/// <summary>
		/// Путь к серверу .arc
		/// </summary>
		public static string ServerPathArc;

		/// <summary>
		/// Путь к клиенту
		/// </summary>
		public static string LocalPath;

        /// <summary>
        /// Путь к контейнеру getxml.sql
        /// </summary>
        public static string FileGetXML;

        /// <summary>
        /// Путь к контейнеру getxml.sql
        /// </summary>
        public static string FileRunSQL;

		/// <summary>
		/// Путь к файлу ATMB.exe - исполняемая утилита ПК Automate
		/// </summary>
		public static string ATMBPath;

		/// <summary>
		/// Список параметров
		/// </summary>
		public static List<Param> Params;

		/// <summary>
		/// Флаг разрешение выполнять задачу
		/// </summary>
		public static bool IsCanRun;

        /// <summary>
        /// Флаг разрешение выполнять задачу
        /// </summary>
        public static bool IsDebug;

		/// <summary>
		/// Флаг разрешение выполнять чтение каталога (во время выполнения задачи каталог не читается)
		/// </summary>
		public static bool IsCanReadTaskDir;

        /// <summary>
        /// Флаг разрешение выполнять задачу
        /// </summary>
        public static bool IsModeOpenFile;


		/// <summary>
		/// Список файлов-задач
		/// </summary>
		public static List<string> FilesTaskList;

		/// <summary>
		/// Список задач
		/// </summary>
		public static List<Task> TaskList;

		#region Itit() -- Инициализация параметров
		/// <summary>
		/// Инициализация параметров
		/// </summary>
		public static void Itit()
		{
			Logs = new Logger("c:\\Automate\\EDIConsole.log");
			Logs.ClearLogs();
			LocalPath = "c:\\Automate";
            FileGetXML = "c:\\Automate\\scripts\\getxml.sql";
            FileRunSQL = "c:\\Automate\\scripts\\runsql.sql";
            ATMBPath = "C:\\Program Files (x86)\\AutoMate 9";
			ClientName = "newClient";
			Params = new List<Param>();
			IsCanRun = true;
			IsCanReadTaskDir = true;
			FilesTaskList = new List<string>();
			TaskList = new List<Task>();
            IsDebug = false;
            IsModeOpenFile = false;

		}
		#endregion

		#region LoadConfig(string filename) -- Чтение файла xml
		/// <summary>
		/// Чтение файла xml
		/// </summary>
		/// <param name="filename">имя файла</param>
		public static void LoadConfig(string filename)
		{
			string spath = "";

			spath = PrjProperty.LocalPath + "\\Property\\";
			XmlTextReader reader = new XmlTextReader(spath + filename);
			bool isXMLconfig = false;
			bool isXMLparams = false;
			string sParamName = "";

			#region while (reader.Read()) -- Чтение XML файла
			while (reader.Read())
			{
				#region XmlNodeType.Element
				if (reader.NodeType == XmlNodeType.Element) //Если элемент 
				{
					#region automate
					if (reader.Name == "automate")
					{
						isXMLconfig = true;
						continue;
					}
					#endregion automate
					#region default-params
					if (isXMLconfig && reader.Name == "default-params")
					{
						isXMLparams = true;
						continue;
					}
					#region param
					if (isXMLconfig && isXMLparams)
					{
						isXMLparams = true;
						sParamName = reader.Name;
					}
					#endregion param
					#endregion default-params
				}
				#endregion XmlNodeType.Element
				#region  XmlNodeType.Text
				if (reader.NodeType == XmlNodeType.Text) //Если элемент
				{
					#region Param
					if (isXMLconfig && isXMLparams && sParamName != "")
					{
						PrjProperty.Params.Add(new Param()
						{
							Name = sParamName,
							Value = reader.Value
						});
					} 
					#endregion
				} 
				#endregion
				#region XmlNodeType.EndElement
				if (reader.NodeType == XmlNodeType.EndElement) //Если элемент 
				{
					#region automate
					if (reader.Name == "automate")
					{
						isXMLconfig = false;
					}
					#endregion 
					#region default-params
					if (isXMLconfig && reader.Name == "default-params")
					{
						isXMLparams = false;
					}
					#endregion 
					#region Param
					if (isXMLconfig && isXMLparams && sParamName != "")
					{
						sParamName = "";
					} 
					#endregion

				}
				#endregion XmlNodeType.EndElement
			}
			#endregion while (reader.Read())

			reader.Close();

			ClientName = GetParam("EDIClientName");
			ServerPath = GetParam("EDIServerPath");
			ServerPathArc = ServerPath + "\\" + ClientName + "\\.arc";
			ATMBPath = GetParam("EDIAtmbPath");

		}
		#endregion LoadConfig

		#region SaveXMLParam (string filename) -- Запись файла xml
		/// <summary>
		/// Запись файла xml
		/// </summary>
		/// <param name="filename">имя файла</param>
		public static void SaveXMLParam(string filename)
		{
			XmlTextWriter writer = new XmlTextWriter(PrjProperty.LocalPath + "\\Property\\" + filename, System.Text.Encoding.Default);
			writer.Formatting = Formatting.Indented;
			writer.WriteStartDocument();
			writer.WriteComment("Created by EDIConsole ver." + Version);
			writer.WriteComment("Date: " + DateTime.Now.ToString());
			writer.WriteStartElement("automate");
			writer.WriteStartElement("default-params");
			foreach (Param param in Params)
			{
				writer.WriteStartElement(param.Name);

				writer.WriteValue(param.Value);
				writer.WriteEndElement();//param
			}

			writer.WriteEndElement();//default-params
			writer.WriteEndElement();//automate
			writer.WriteEndDocument();
			writer.Close();

		}
		#endregion SaveXMLParam

		#region LoadXMLrun(string filename) -- Чтение файла xml
		/// <summary>
		/// Чтение файла xml
		/// </summary>
		/// <param name="filename">имя файла</param>
		public static void LoadXMLrun(string filename)
		{
			Logs.WriteLogs("Открытие " + filename);
			XmlTextReader reader = new XmlTextReader(filename);
			bool isEdiAutomate = false;
			bool isEdiCommand = false;
			bool isEdiRunApp = false;
            bool isEdiRunTask = false;
            bool isEdiGetXml = false;
            bool isEdiRunSQL = false;
            bool isEdiRunTaskFile = false;
			Task task = new Task();

			DateTime commandDate = DateTime.Today;
			#region while (reader.Read())
			while (reader.Read())
			{
				#region XmlNodeType.Element
				if (reader.NodeType == XmlNodeType.Element) //Если элемент 
				{
					#region automate
					if (reader.Name.ToLower() == "automate")
					{
						isEdiAutomate = true;
					}
					#endregion automate
					#region ediruntask
					if (isEdiAutomate && reader.Name.ToLower() == "ediruntask")
					{
						isEdiRunTask = true;
						string sdate = reader.GetAttribute("startdate") == null ? DateTime.Now.ToShortDateString() : reader.GetAttribute("startdate");
						string stime = reader.GetAttribute("starttime") == null ? DateTime.Now.ToShortTimeString() : reader.GetAttribute("starttime"); ;
						task = new Task();
						task.FileName = filename;
						commandDate = Convert.ToDateTime(sdate + " " + stime);
						task.Name = "Task " + commandDate.ToString();
						task.DateStart = commandDate;
						PrjProperty.TaskList.Add(task);
					}
					
					#region file
					if (isEdiAutomate && isEdiRunTask && reader.Name.ToLower() == "file")
					{
						isEdiRunTaskFile = true;
						task.DateStart = commandDate;
						int taskListCount = PrjProperty.TaskList.Count - 1;
						PrjProperty.TaskList[taskListCount].Commands.Add(new TskCommand() { TypeCmd = "automate-run" });
					} 
					#endregion file
					#endregion ediruntask
					#region edicommand
					#region command
					if (isEdiAutomate && reader.Name.ToLower() == "edicommand")
					{
						isEdiCommand = true;
						string sdate = reader.GetAttribute("startdate");
						string stime = reader.GetAttribute("starttime");
						task = new Task();
						task.FileName = filename;
						commandDate = Convert.ToDateTime(sdate + " " + stime);
						task.Name = "Task " + commandDate.ToString();
						task.DateStart = commandDate;
						PrjProperty.TaskList.Add(task);
					}
					#endregion command
					#region run
					if (isEdiAutomate && isEdiCommand && reader.Name == "run")
					{
						isEdiRunApp = true;
						task.DateStart = commandDate;
						int taskListCount = PrjProperty.TaskList.Count - 1;
                        PrjProperty.TaskList[taskListCount].Commands.Add(new TskCommand() { TypeCmd = "automate-run" });
					}
					#endregion run
                    #region getxml
                    if (isEdiAutomate && isEdiCommand && reader.Name == "getxml")
                    {
                        isEdiGetXml = true;
                        task.DateStart = commandDate;
                        string name = reader.GetAttribute("name");
                        string file = reader.GetAttribute("file");
                        string resultdir = reader.GetAttribute("resultdir");
                        int taskListCount = PrjProperty.TaskList.Count - 1;
                        TskCommand tskcommand = new TskCommand { TypeCmd = "getxml" };
                        tskcommand.Params.Add(new Param() { Name = "name", Value = name });
                        tskcommand.Params.Add(new Param() { Name = "file", Value = file });
                        tskcommand.Params.Add(new Param() { Name = "resultdir", Value = resultdir });
                        PrjProperty.TaskList[taskListCount].Commands.Add(tskcommand);

                    }
                    #endregion getxml
                    #region runsql
                    if (isEdiAutomate && isEdiCommand && reader.Name == "runsql")
                    {
                        isEdiRunSQL = true;
                        task.DateStart = commandDate;
                        string name = reader.GetAttribute("name");
                        string file = reader.GetAttribute("file");
                        string resultdir = reader.GetAttribute("resultdir");
                        int taskListCount = PrjProperty.TaskList.Count - 1;
                        TskCommand tskcommand = new TskCommand { TypeCmd = "runsql" };
                        tskcommand.Params.Add(new Param() { Name = "name", Value = name });
                        tskcommand.Params.Add(new Param() { Name = "file", Value = file });
                        tskcommand.Params.Add(new Param() { Name = "resultdir", Value = resultdir });
                        PrjProperty.TaskList[taskListCount].Commands.Add(tskcommand);

                    }
                    #endregion runsql
                    #region copy
                    if (isEdiAutomate && isEdiCommand && reader.Name == "copy")
					{
						isEdiCommand = true;
						string scopyfrom = reader.GetAttribute("copyfrom");
						string scopyto = reader.GetAttribute("copyto");
						string isparam = reader.GetAttribute("isparam");
						int taskListCount = PrjProperty.TaskList.Count - 1;
						TskCommand tskcommand = new TskCommand { TypeCmd = "copy" };
						tskcommand.Params.Add(new Param() { Name = "FileName", Value = scopyfrom });
						tskcommand.Params.Add(new Param() { Name = "CopyToPath", Value = scopyto });
						tskcommand.Params.Add(new Param() { Name = "ParamIsUseParam", Value = isparam });
						PrjProperty.TaskList[taskListCount].Commands.Add(tskcommand);
					}
					#endregion copy
					#region change-param
					if (isEdiAutomate && isEdiCommand && reader.Name == "change-param")
					{
						isEdiCommand = true;
						string sname = reader.GetAttribute("name");
						string svalue = reader.GetAttribute("value");

						int taskListCount = PrjProperty.TaskList.Count - 1;
						TskCommand tskcommand = new TskCommand { TypeCmd = "change-param" };
						tskcommand.Params.Add(new Param() { Name = "Name", Value = sname });
						tskcommand.Params.Add(new Param() { Name = "Value", Value = svalue });
						PrjProperty.TaskList[taskListCount].Commands.Add(tskcommand);

					}
					#endregion change-param
					#region update
					if (isEdiAutomate && isEdiCommand && reader.Name == "update")
					{
						isEdiCommand = true;
						string sfile = reader.GetAttribute("file");

						int taskListCount = PrjProperty.TaskList.Count - 1;
						TskCommand tskcommand = new TskCommand { TypeCmd = "update" };
						tskcommand.Params.Add(new Param() { Name = "file", Value = sfile });
						PrjProperty.TaskList[taskListCount].Commands.Add(tskcommand);
					}
					#endregion update
					#endregion command
				}
				#endregion XmlNodeType.Element

				#region XmlNodeType.Text
				if (reader.NodeType == XmlNodeType.Text) //Если Text 
				{
					#region EdiCommand.EdiRunApp
					if (isEdiAutomate && isEdiCommand && isEdiRunApp)
					{
						int taskListCount = PrjProperty.TaskList.Count - 1;
						int commandCount = PrjProperty.TaskList[taskListCount].Commands.Count - 1;
						PrjProperty.TaskList[taskListCount].Commands[commandCount].Params.Add(new Param() { Name = "FileName", Value = reader.Value });
					}
					#endregion edicommand.run
					#region EdiRunTask.EdiRunTaskFile
					if (isEdiAutomate && isEdiRunTask && isEdiRunTaskFile)
					{
						int taskListCount = PrjProperty.TaskList.Count - 1;
						int commandCount = PrjProperty.TaskList[taskListCount].Commands.Count - 1;
						PrjProperty.TaskList[taskListCount].Commands[commandCount].Params.Add(new Param() { Name = "FileName", Value = reader.Value });
					}
					#endregion EdiRunTask.EdiRunTaskFile
                    #region EdiCommand.EdiGetXml
                    if (isEdiAutomate && isEdiCommand && isEdiGetXml)
                    {
                        int taskListCount = PrjProperty.TaskList.Count - 1;
                        int commandCount = PrjProperty.TaskList[taskListCount].Commands.Count - 1;
                        PrjProperty.TaskList[taskListCount].Commands[commandCount].Params.Add(new Param() { Name = "sql", Value = reader.Value });
                    }
                    #endregion edicommand.EdiGetXml
                }
				#endregion XmlNodeType.Text

				#region XmlNodeType.EndElement
				if (reader.NodeType == XmlNodeType.EndElement) //Если элемент 
				{
					#region automate
					if (reader.Name == "automate")
					{
						isEdiAutomate = false;
					}
					#endregion automate
					#region ediruntask
					if (isEdiAutomate && reader.Name.ToLower() == "ediruntask")
					{
						isEdiRunTask = false;
					}
					#region file
					if (isEdiAutomate && isEdiRunTask && reader.Name.ToLower() == "file")
					{
						isEdiRunTaskFile = false;
					}
					#endregion file
                    #region getxml
                    if (isEdiAutomate && isEdiRunTask && reader.Name.ToLower() == "getxml")
                    {
                        isEdiGetXml = false;
                    }
                    #endregion getxml
                    #region runsql
                    if (isEdiAutomate && isEdiRunTask && reader.Name.ToLower() == "runsql")
                    {
                        isEdiRunSQL = false;
                    }
                    #endregion runsql
                    #endregion ediruntask
                    #region edicommand
                    if (reader.Name.ToLower() == "edicommand")
					{
						isEdiCommand = false;
						int taskListCount = PrjProperty.TaskList.Count - 1;
						//listBox1.Items.Add(PrjProperty.TaskList[taskListCount].Name);
					}

                    #region run
                    if (reader.Name == "run")
                    {
                        isEdiRunApp = false;
                        int taskListCount = PrjProperty.TaskList.Count - 1;
                        int commandCount = PrjProperty.TaskList[taskListCount].Commands.Count - 1;
                        //listBox1.Items.Add(PrjProperty.TaskList[taskListCount].Command[commandCount].Command);
                    }
                    #endregion run
                
                    #endregion edicommand
				}
				#endregion XmlNodeType.EndElement
			}
			#endregion while (reader.Read())
			reader.Close();
		}
		#endregion LoadXMLrun

		#region string GetParam(string sName) -- Поиск значения параметра
		/// <summary>
		/// Поиск значения параметра
		/// </summary>
		/// <param name="sName">Имя параметра</param>
		/// <returns>Значения параметра</returns>
		public static string GetParam(string sName)
		{
			string ret = null;
			ret = "";
			foreach (Param prm in Params)
			{
				if (prm.Name.ToLower() == sName.ToLower())
					ret = prm.Value;
			}
			return ret;
		}
		#endregion GetParam

		#region RunTask -- Выполнение задач
		/// <summary>
		/// Выполнение задач
		/// </summary>
		public static void RunTask(Object state)
		{
			if (IsCanRun)
			{
				RunTaskAll();
			}
		}
		#endregion RunTask

		#region RunTaskAll() -- Выполнение команд в задаче
		/// <summary>
		/// Выполнение команд в задаче
		/// </summary>
		public static void RunTaskAll()
		{
			IsCanRun = false;
			IsCanReadTaskDir = false;
			foreach (Task task in TaskList)
			{
				if (task.DateStart < DateTime.Now && task.Name != "del")
				{
					PrjProperty.Logs.WriteLogs("Выполнение " + task.Name);
					string res = task.RunCommandAll();
                    PrjProperty.Logs.WriteLogs("Выполнено: " + res);
					string strfname = Path.GetFileName(task.FileName);
					string pathDist = PrjProperty.ServerPathArc + "\\" + strfname;
                    if (!IsModeOpenFile)
                    {
                        if (File.Exists(pathDist)) File.Delete(pathDist);
                        File.Move(task.FileName, pathDist);

                        task.Name = "del";
                    }
					if (res.ToLower() == "exit;")
					{
						Environment.Exit(0);
					}

				}
			}
			IsCanReadTaskDir = true;
			IsCanRun = true;
            Logs.WriteLogs("IsCanReadTaskDir = true; IsCanRun = true;");
		}
		#endregion RunTaskAll()

        #region AddTask(string filename) -- Добавить задачу
        /// <summary>
        /// Добавить задачу
        /// </summary>
        static public void AddTask(string filename)
        {
            FilesTaskList.Add(filename);
            Logs.WriteLogs("Add: " + DateTime.Now.ToString("h:mm:ss") + "; file: " + filename);
            LoadXMLrun(filename);
        }
        #endregion AddTask()

        #region bool GetFilesTaskList() -- Получить Список файлов в папке
        /// <summary>
		/// Получить Список файлов в папке
		/// </summary>
		static public bool GetFilesTaskList()
		{

			string[] filePaths = Directory.GetFiles(PrjProperty.ServerPath + "\\" + PrjProperty.ClientName);
			//Creating a new List<T> of type <string>
			List<string> FilesList = new List<string>(filePaths.Length);
			bool isNotDirEmpty = filePaths.Length > 0 ? true : false;
            if (IsDebug) Logs.WriteLogs("Чтение каталога, результат " + isNotDirEmpty.ToString());
			if (isNotDirEmpty)
			{
				FilesList.AddRange(filePaths);

				#region Добавление в список задач
				foreach (string sfile in FilesList)
				{
					//Console.WriteLine("Read: {0}; file: {1}", DateTime.Now.ToString("h:mm:ss"), sfile);

					if (FilesTaskList.FindIndex(item => item == sfile) == -1)
					{
						FilesTaskList.Add(sfile);
						Logs.WriteLogs("Add: " + DateTime.Now.ToString("h:mm:ss") + "; file: " + sfile);
						LoadXMLrun(sfile);
					}
				}
				#endregion
			}
			#region Удаление пропавших из папки задач
			if (FilesTaskList.Count > 0)
			{
				List<string> dellist = new List<string>();
				foreach (string sfile in FilesTaskList)
				{
					if (FilesList.FindIndex(item => item == sfile) == -1)
					{
						dellist.Add(sfile);
					}
				}
				foreach (string sfile in dellist)
				{
					int index = PrjProperty.FilesTaskList.FindIndex(item => item == sfile);
					if (index > -1)
					{
						FilesTaskList.RemoveAt(index);
						Logs.WriteLogs("Delete: " + DateTime.Now.ToString("h:mm:ss") + "; file: " + sfile);

					}
				}
			}
			#endregion

			return isNotDirEmpty;
		}
		#endregion GetFilesTaskList()

		#region ReadTaskDir -- Чтение папки на сервере с задачами
		/// <summary>
		/// Чтение папки на сервере с задачами
		/// </summary>
		static public void ReadTaskDir(Object stateInfo)
		{
            if (IsDebug) Logs.WriteLogs("Таймер: " + IsCanReadTaskDir.ToString());
            if (IsCanReadTaskDir)
				GetFilesTaskList();
		}
		#endregion ReadTaskDir

	}
}
